home *** CD-ROM | disk | FTP | other *** search
/ The Very Best of Atari Inside / The Very Best of Atari Inside 1.iso / mint / mgr_2 / contrib / atari / vt52.c < prev   
C/C++ Source or Header  |  1990-09-29  |  6KB  |  317 lines

  1. #include "term.h"
  2. #include <osbind.h>
  3. #include <mintbind.h>
  4. #include <keycodes.h>
  5. #include <process.h>
  6. #include <signal.h>
  7. #include <sgtty.h>
  8.  
  9. /* key that gets us out of VT52 -- ^G, for now */
  10. #define QUITKEY '\007'
  11. extern void normal_putch(), escy_putch();
  12.  
  13. int kidpid;        /* child's process id */
  14. int kidfd;        /* child's file descriptor */
  15. int savex, savey;    /* saved x, y coordinates */
  16. void (*state)();
  17.  
  18. /*
  19.  * clrfrom(x1, y1, x2, y2): clear screen from position (x1,y1) to
  20.  * position (x2, y2) inclusive. It is assumed that y2 >= y1.
  21.  */
  22.  
  23. void
  24. clrfrom(x1, y1, x2, y2)
  25.     int x1,y1,x2,y2;
  26. {
  27. }
  28.  
  29. void
  30. ignore()
  31. {
  32.     state = normal_putch;
  33. }
  34.  
  35. /*
  36.  * putesc(v, c): handle the control sequence ESC c
  37.  */
  38.  
  39. #define gotoxy(x, y) m_move(x, y)
  40.  
  41. void
  42. putesc(c)
  43.     int c;
  44. {
  45.     int cx, cy;
  46.  
  47.     switch (c) {
  48.     case 'A':        /* cursor up */
  49.         m_up(10);    /* BUG -- this scrolls; it shouldn't */
  50.         break;
  51.     case 'B':        /* cursor down */
  52.         m_down(10);    /* BUG -- this scrolls; it shouldn't */
  53.         break;
  54.     case 'C':        /* cursor right */
  55.         m_right(10);
  56.         break;
  57.     case 'D':        /* cursor left */
  58.         m_left(10);
  59.         break;
  60.     case 'E':        /* clear home */
  61.         m_clear();
  62.         break;
  63.     case 'H':        /* cursor home */
  64.         gotoxy(0, 0);
  65.         break;
  66.     case 'I':        /* cursor up, insert line */
  67.         m_up(10);
  68.         break;
  69.     case 'J':        /* clear below cursor */
  70.         m_cleareos();
  71.         break;
  72.     case 'K':        /* clear remainder of line */
  73.         m_cleareol();
  74.         break;
  75.     case 'L':        /* insert a line */
  76.         m_addline();
  77.         break;
  78.     case 'M':        /* delete line */
  79.         m_deleteline();
  80.         break;
  81.     case 'Y':
  82.         state = escy_putch;
  83.         return;        /* YES, this should be 'return' */
  84.     case 'b':        /* set foreground color */
  85.     case 'c':        /* set background color */
  86.         state = ignore;
  87.         return;
  88.     case 'd':        /* clear to cursor position */
  89.         get_cursor(&cx, &cy);
  90.         clrfrom(0, 0, cx, cy);
  91.         break;
  92.     case 'e':        /* enable cursor */
  93.         m_setcursor(CS_BLOCK);
  94.         break;
  95.     case 'f':        /* cursor off */
  96.         m_setcursor(CS_INVIS);
  97.         break;
  98.     case 'j':        /* save cursor position */
  99.         get_cursor(&savex, &savey);
  100.         break;
  101.     case 'k':        /* restore saved position */
  102.         gotoxy(savex, savey);
  103.         break;
  104.     case 'l':        /* clear line */
  105.         get_cursor(&cx, &cy);
  106.         gotoxy(0, cy);
  107.         m_cleareol();
  108.         break;
  109.     case 'o':        /* clear from start of line to cursor */
  110.         get_cursor(&cx, &cy);
  111.         clrfrom(0, cy, cx, cy);
  112.         break;
  113.     case 'p':        /* reverse video on */
  114.         m_standout();
  115.         break;
  116.     case 'q':        /* reverse video off */
  117.         m_standend();
  118.         break;
  119.     case 'v':        /* wrap on */
  120.         m_clearmode(M_NOWRAP);
  121.         break;
  122.     case 'w':
  123.         m_setmode(M_NOWRAP);
  124.         break;
  125.     }
  126.     state = normal_putch;
  127. }
  128.  
  129. /*
  130.  * escy1_putch(c): for when an ESC Y + char has been seen
  131.  */
  132.  
  133. int escy1;
  134.  
  135. void
  136. escy1_putch(c)
  137.     int c;
  138. {
  139.     gotoxy(c - ' ', escy1 - ' ');
  140.     state = normal_putch;
  141. }
  142.  
  143. /*
  144.  * escy_putch(v, c): for when an ESC Y has been seen
  145.  */
  146.  
  147. void
  148. escy_putch(c)
  149.     int c;
  150. {
  151.     escy1 = c;
  152.     state = escy1_putch;
  153. }
  154.  
  155. /*
  156.  * normal_putch(c): put character 'c' on screen. This is the default
  157.  * for when no escape, etc. is active
  158.  */
  159.  
  160. void
  161. normal_putch(c)
  162.     int c;
  163. {
  164.     if (c == '\033')
  165.         state = putesc;
  166.     else
  167.         m_putchar(c);
  168. }
  169.  
  170. static inline
  171. void
  172. put_ch(c)
  173.     int c;
  174. {
  175.     (*state)(c);
  176. }
  177.  
  178. int
  179. run(shell, argv)
  180.     char *shell, **argv;
  181. {
  182.     int fd, oldtty;
  183.     long pid;
  184.     static char pty[] = "Q:\\VT52@";
  185.  
  186. /* create our handle */
  187.     pid = 0;
  188.     do {
  189.         pty[7]++; pid++;
  190.         fd = Fcreate(pty, FA_SYSTEM|FA_HIDDEN);
  191.     } while (fd < 0 && pid < 8);
  192.  
  193.     if (fd < 0) {
  194.         printf("couldn't create a pty\n");
  195.         quit(2);
  196.     }
  197.     kidfd = fd;
  198.  
  199. /* now create the child's handle */
  200.     fd = Fopen(pty, 2);
  201.  
  202.     oldtty = Fdup(-1);
  203.     if (oldtty < 0) {
  204.         Cconws("couldn't dup control terminal!\r\n");
  205.         quit(2);
  206.     }
  207.     Fforce(-1, fd);            /* set up new control terminal */
  208.     Fforce(0, fd);
  209.     Fforce(1, fd);
  210.     Fforce(2, fd);
  211.     pid = spawnvp(P_NOWAIT, shell, argv); /* spawn child in background */
  212.     Fforce(-1, oldtty);
  213.     Fforce(0, oldtty);
  214.     Fforce(1, oldtty);
  215.     Fforce(2, oldtty);
  216.     if (pid < 0) {
  217.         Cconws("couldn't run ");
  218.         Cconws(shell);
  219.         Cconws("\r\n");
  220.         quit((int)pid);
  221.     }
  222.     Psetpgrp((int)pid, (int)pid);    /* set the child's process group */
  223.     Fcntl(fd, &pid, TIOCSPGRP);    /* set the terminal process group */
  224.     Fclose(fd);
  225.  
  226.     kidpid = pid;
  227.     return kidfd;
  228. }
  229.  
  230. int
  231. quit(x)
  232.     int x;
  233. {
  234.     m_setnoraw();
  235.     if (kidpid)
  236.         Pkill((int)-kidpid, SIGHUP);
  237.     Pterm(x);
  238. }
  239.  
  240. #define INBUFSIZ 256
  241.  
  242. main(argc, argv)
  243.     int argc;
  244.     char **argv;
  245. {
  246.     int fd;
  247.     long s, c;
  248.     long reads, fdmask;
  249.     unsigned char cbuf[INBUFSIZ], *cb;
  250.     char *shell, *getenv();
  251.     struct sgttyb sg;
  252.  
  253.     if (argc == 3 && !strcmp(argv[1], "-f")) {
  254.         fd = Fopen(argv[2], 2);
  255.         if (fd < 0) {
  256.             perror(argv[2]);
  257.             exit(1);
  258.         }
  259.         s = Pgetpgrp();
  260.         Fcntl(fd, &s, TIOCSPGRP);
  261.         Fcntl(fd, &sg, TIOCGETP);
  262.         sg.sg_flags = RAW;
  263.         Fcntl(fd, &sg, TIOCSETP);
  264.     }
  265.     else {
  266.         if (argv[1]) {
  267.             argv++;
  268.             shell = argv[0];
  269.         }
  270.         else {
  271.             shell = getenv("SHELL");
  272.             if (!shell) shell="init.prg";
  273.             argv[0] = shell;
  274.             argv[1] = 0;
  275.         }
  276.         fd = run(shell, argv);
  277.     }
  278.  
  279.     m_setup(0);
  280.  
  281.     m_size(80, 25);
  282.     m_clear();
  283.     m_setraw();
  284.     m_setmode(M_NOBUCKEY);
  285.  
  286.     state = normal_putch;
  287.  
  288.     fdmask = 1L << fd;
  289.  
  290.     for(;;) {
  291.         reads = 1 | fdmask;
  292.         Fselect(0, &reads, 0L, 0L);
  293.  
  294.         if (reads & fdmask) {
  295.             s = Finstat(fd);
  296.             if (s > 0) {
  297.                 if (s > INBUFSIZ) s = INBUFSIZ;
  298.                 cb = cbuf;
  299.                 s = Fread(fd, s, cb);
  300.                 while (s-- > 0)
  301.                     put_ch(*cb++);
  302.                 m_flush();
  303.             }
  304.             else if (s < 0) {
  305.                 Cconws("Child exited??\r\n");
  306.                 quit((int)s);
  307.             }
  308.         }
  309.         if (reads & 1) {
  310.                 c = Fgetchar(0, 0);
  311.                 if ( (c & 0xff) == QUITKEY )
  312.                     quit(0);
  313.                 Fputchar(fd, c, 0);
  314.         }
  315.     }
  316. }
  317.